package com.swiot.biz.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.swiot.biz.constants.TemplateConstants;

import java.util.List;

/**
 * SQL生成工具类
 * 
 * @author system
 */
@Component
public class SqlGenerator {
    
    private static final Logger log = LoggerFactory.getLogger(SqlGenerator.class);
    
    /**
     * 生成创建表的SQL语句
     * 
     * @param tableName 表名
     * @param fields 字段列表
     * @param groupName 分组名称
     * @return 创建表的SQL语句
     */
    public String generateCreateTableSQL(String tableName, List<String> fields, String groupName) {
        try {
            log.info("开始生成创建表SQL，表名：{}，字段数量：{}，分组名称：{}", tableName, fields.size(), groupName);
            
            StringBuilder sql = new StringBuilder();
         //   sql.append("DROP TABLE IF EXISTS ").append(tableName).append(";\n");
            sql.append("CREATE TABLE `").append(tableName).append("` (");
            sql.append("  id bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',");
            // 添加标准字段
            sql.append("  `template_id` bigint NOT NULL DEFAULT '0' COMMENT '模板ID',");
            sql.append("  `template_data_id` bigint NOT NULL DEFAULT '0' COMMENT '模板数据ID',");
            sql.append("  `dept_id` bigint NOT NULL DEFAULT '0' COMMENT '部门id',");
            sql.append("  `report_date` VARCHAR(20) NOT NULL COMMENT '报表日期',");
            sql.append("  `data_type` VARCHAR(4) NOT NULL COMMENT '数据类型',");
            sql.append("  `segment_name` VARCHAR(100) NOT NULL COMMENT '板块信息',");
            sql.append("  `publish_status` tinyint NOT NULL DEFAULT 1 COMMENT '发布状态：0-未发布，1-已发布',");
            sql.append("  `del_flag` char(1) NOT NULL DEFAULT '0' COMMENT '删除标志（0代表存在 2代表删除）',");
            sql.append("  `created_time` datetime NOT NULL COMMENT '创建时间',");
            sql.append("  `updated_time` datetime DEFAULT NULL COMMENT '更新时间',");
            sql.append("  `deleted_time` datetime NULL DEFAULT NULL COMMENT '删除时间',");
            sql.append("  `created_by_id` bigint NULL COMMENT '创建人用户ID',");
            sql.append("  `updated_by_id` bigint NULL COMMENT '最后更新人用户ID',");
            sql.append("  `created_by` VARCHAR(64) NULL COMMENT '创建人',");
            sql.append("  `updated_by` VARCHAR(64) NULL COMMENT '最后更新人',");
            sql.append("  `description` VARCHAR(100) DEFAULT NULL COMMENT '描述',");
            // 添加业务字段
            for (int i = 0; i < fields.size(); i++) {
                String field = fields.get(i);
                String fieldName = convertToValidFieldName(field);
                log.info("字段处理：原始字段名='{}'，生成字段名='{}'", field, fieldName);
                sql.append("  `").append(fieldName).append("` VARCHAR(25) NULL COMMENT '").append(escapeSqlComment(field)).append("',");
            }
            sql.append("  PRIMARY KEY (`id`) USING BTREE,");
            sql.append("  INDEX `idx_publish_status` (`publish_status`) USING BTREE,");
            sql.append("  INDEX `idx_dept_id` (`dept_id`) USING BTREE,");
            sql.append("  INDEX `idx_template_data_id` (`template_data_id`) USING BTREE,");
            sql.append("  INDEX `idx_report_date` (`report_date`) USING BTREE,");
            sql.append("  INDEX `idx_segment_name` (`segment_name`) USING BTREE,");
            sql.append("  INDEX `idx_created_time` (`created_time`) USING BTREE");
            sql.append(") ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT '").append(escapeSqlComment(tableName)).append("表';");
            
            String resultSql = sql.toString();
            log.info("生成创建表SQL完成，SQL长度：{}", resultSql.length());
            log.debug("生成的SQL：\n{}", resultSql);
            
            return resultSql;
            
        } catch (Exception e) {
            log.error("生成创建表SQL时发生错误：", e);
            return "";
        }
    }

    /**
     * 生成修改表的SQL语句（添加字段）
     *
     * @param tableName 表名
     * @param fields 字段列表
     * @return 修改表的SQL语句
     */
    public String generateAlterTableSQL(String tableName, List<String> fields) {
        try {
            log.info("开始生成修改表SQL，表名：{}，字段数量：{}", tableName, fields.size());

            StringBuilder sql = new StringBuilder();
                            // 为每个字段生成ALTER TABLE ADD COLUMN IF NOT EXISTS语句

            sql.append("ALTER TABLE `").append(tableName).append("` ");
                for (int i = 0; i < fields.size(); i++) {
                    String field = fields.get(i);
                    String fieldName = convertToValidFieldName(field);
                    log.info("字段处理：原始字段名='{}'，生成字段名='{}'", field, fieldName);

                    sql.append("ADD COLUMN `").append(fieldName).append("` VARCHAR(25) NULL ");
                    sql.append("COMMENT '").append(escapeSqlComment(field)).append("';");

                    // 如果不是最后一个字段，添加换行
                    if (i < fields.size() - 1) {
                        sql.append("\n");
                    }
                }

            String resultSql = sql.toString();
            log.info("生成修改表SQL完成，SQL长度：{}", resultSql.length());
            log.debug("生成的SQL：\n{}", resultSql);

            return resultSql;

        } catch (Exception e) {
            log.error("生成修改表SQL时发生错误：", e);
            return "";
        }
    }
    
    /**
     * 将字段名转换为有效的数据库字段名
     * 保持中文字段名，但确保符合数据库规范
     * 
     * @param fieldName 原始字段名
     * @return 有效的数据库字段名
     */
    public String convertToValidFieldName(String fieldName) {
        if (fieldName == null || fieldName.trim().isEmpty()) {
            return "field_" + System.currentTimeMillis();
        }
        
        // 移除首尾空格
        String trimmedField = fieldName.trim();
        
        // 检查字段名是否包含特殊字符或关键字
        if (isValidFieldName(trimmedField)) {
            // 如果字段名有效，直接使用（包括中文）
            return trimmedField;
        } else {
            // 如果字段名无效，生成安全的字段名
            return generateSafeFieldName(trimmedField);
        }
    }
    
    /**
     * 检查字段名是否有效（符合数据库规范）
     * 
     * @param fieldName 字段名
     * @return 是否有效
     */
    private boolean isValidFieldName(String fieldName) {
        if (fieldName == null || fieldName.isEmpty()) {
            return false;
        }
        
        // 检查是否以数字开头
        if (Character.isDigit(fieldName.charAt(0))) {
            return false;
        }
        
        // 检查是否包含SQL关键字
        if (isSqlKeyword(fieldName)) {
            return false;
        }
        
        // 检查是否包含特殊字符（除了中文、英文、数字、下划线）
        for (char c : fieldName.toCharArray()) {
            if (!Character.isLetterOrDigit(c) && c != '_' && !isChinese(c)) {
                return false;
            }
        }
        
        return true;
    }
    
    /**
     * 检查字符是否为中文字符
     * 
     * @param c 字符
     * @return 是否为中文
     */
    private boolean isChinese(char c) {
        return Character.UnicodeScript.of(c) == Character.UnicodeScript.HAN;
    }
    
    /**
     * 检查是否为SQL关键字
     * 
     * @param fieldName 字段名
     * @return 是否为SQL关键字
     */
    private boolean isSqlKeyword(String fieldName) {
        if (fieldName == null) {
            return false;
        }
        
        String upperFieldName = fieldName.toUpperCase();
        String[] sqlKeywords = {
            "SELECT", "FROM", "WHERE", "INSERT", "UPDATE", "DELETE", "CREATE", "DROP", "TABLE", "INDEX",
            "PRIMARY", "KEY", "FOREIGN", "REFERENCES", "UNIQUE", "NOT", "NULL", "DEFAULT", "AUTO_INCREMENT",
            "ORDER", "BY", "GROUP", "HAVING", "JOIN", "LEFT", "RIGHT", "INNER", "OUTER", "ON", "AS",
            "DISTINCT", "COUNT", "SUM", "AVG", "MAX", "MIN", "AND", "OR", "IN", "BETWEEN", "LIKE",
            "IS", "EXISTS", "UNION", "ALL", "CASE", "WHEN", "THEN", "ELSE", "END", "IF", "LIMIT",
            "OFFSET", "ASC", "DESC", "COMMENT", "ENGINE", "CHARSET", "COLLATE", "CONSTRAINT", "CHECK"
        };
        
        for (String keyword : sqlKeywords) {
            if (upperFieldName.equals(keyword)) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * 生成安全的字段名
     * 
     * @param originalFieldName 原始字段名
     * @return 安全的字段名
     */
    private String generateSafeFieldName(String originalFieldName) {
        // 使用时间戳和哈希值生成唯一字段名
        String timestamp = String.valueOf(System.currentTimeMillis());
        int hashCode = Math.abs(originalFieldName.hashCode());
        
        // 生成字段名：field_时间戳_哈希值
        return "field_" + timestamp.substring(timestamp.length() - 6) + "_" + (hashCode % 10000);
    }
    
    /**
     * 转义SQL注释中的特殊字符
     * 
     * @param comment 原始注释
     * @return 转义后的注释
     */
    private String escapeSqlComment(String comment) {
        if (comment == null) {
            return "";
        }
        
        // 转义单引号
        return comment.replace("'", "''");
    }
    
    /**
     * 将驼峰命名转换为下划线命名
     * 
     * @param camelCase 驼峰命名字符串
     * @return 下划线命名字符串
     */
    private String convertToSnakeCase(String camelCase) {
        if (camelCase == null || camelCase.isEmpty()) {
            return camelCase;
        }
        
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < camelCase.length(); i++) {
            char c = camelCase.charAt(i);
            if (Character.isUpperCase(c)) {
                if (i > 0) {
                    result.append('_');
                }
                result.append(Character.toLowerCase(c));
            } else {
                result.append(c);
            }
        }
        
        return result.toString();
    }
    
    /**
     * 生成表名
     * 
     * @param templateName 模板名称
     * @return 表名
     */
    public String generateTableName(String templateName,String prefix) {
        if (templateName == null || templateName.trim().isEmpty()) {
            return TemplateConstants.DEFAULT_TABLE_PREFIX+ prefix + "template" ;
        }
        
        // 移除特殊字符，转换为小写，用下划线替换空格
        String tableName = templateName.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5]", "_")
                                     .toLowerCase()
                                     .replaceAll("_+", "_")
                                     .replaceAll("^_|_$", "");
        
        // 如果为空，使用默认名称
        if (tableName.isEmpty()) {
            tableName = "none_data";
        }
        
        // 添加前缀
        return TemplateConstants.DEFAULT_TABLE_PREFIX + prefix+ tableName ;
    }

    /**
     * 生成告警表名
     *
     * @param templateName 模板名称
     * @return 告警表名
     */
    public String generateAlarmTableName(String templateName) {
        if (templateName == null || templateName.trim().isEmpty()) {
            return TemplateConstants.DEFAULT_TABLE_PREFIX+ TemplateConstants.DEFAULT_ALARM_SUFFIX + "template" ;
        }

        // 移除特殊字符，转换为小写，用下划线替换空格
        String tableName = templateName.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5]", "_")
                                    .toLowerCase()
                                    .replaceAll("_+", "_")
                                    .replaceAll("^_|_$", "");

        // 如果为空，使用默认名称
        if (tableName.isEmpty()) {
            tableName = "none_alarm";
        }

        // 添加前缀
        return TemplateConstants.DEFAULT_TABLE_PREFIX + TemplateConstants.DEFAULT_ALARM_SUFFIX+ tableName ;
    }

    /**
     * 生成提醒表名
     * @param templateName
     * @return
     */
    public String generateRemindTableName(String templateName) {
        if (templateName == null || templateName.trim().isEmpty()) {
            return TemplateConstants.DEFAULT_TABLE_PREFIX+ TemplateConstants.DEFAULT_REMIND_SUFFIX + "template" ;
        }

        // 移除特殊字符，转换为小写，用下划线替换空格
        String tableName = templateName.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5]", "_")
                                   .toLowerCase()
                                   .replaceAll("_+", "_")
                                   .replaceAll("^_|_$", "");

        // 如果为空，使用默认名称
        if (tableName.isEmpty()) {
            tableName = "none_remind";
        }

        // 添加前缀
        return TemplateConstants.DEFAULT_TABLE_PREFIX + TemplateConstants.DEFAULT_REMIND_SUFFIX+ tableName ;
    }
}
